﻿using System;
using System.Collections.Generic;
using System.Reflection;

namespace Needle.Utils
{
    /// <summary>
    /// Helper functions for types.
    /// </summary>
    public static class Types
    {
        /// <summary>
        /// Gets the type by name
        /// </summary>
        public static Type GetType(String name)
        {
            return GetType(name, false, false);
        }
        /// <summary>
        /// Gets the type by name
        /// </summary>
        public static Type GetType(String name, bool throwOnError)
        {
            return GetType(name, throwOnError, false);
        }
        /// <summary>
        /// Gets the type by name
        /// </summary>
        public static Type GetType(String name, bool throwOnError, bool ignoreCase)
        {
            Type t;
            t = Type.GetType(name, false, ignoreCase);
            if (t != null)
                return t;

            foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
            {
                t = asm.GetType(name, false, ignoreCase);
                if (t != null)
                    break;
            }

            if (throwOnError && t == null)
                throw new TypeLoadException("Type " + name + " not found, did you qualify the assembly?");

            return t;
        }
        /// <summary>
        /// Gets the type by name
        /// </summary>
        public static IEnumerable<Type> GetAll()
        {
            foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (Type t in asm.GetTypes())
                {
                    yield return t;
                }
            }
            yield break;
        }
        /// <summary>
        /// returns true if t is one of System.Byte, System.Double, System.Int16, System.Int32, System.Int64, System.SByte, System.Single, System.UInt16, System.UInt32, System.UInt64
        /// </summary>
        public static bool IsNumeric(Type t)
        {
            return t.IsPrimitive &&  !t.IsPointer && t.IsValueType &&t != typeof(char) && t != typeof(bool) && t != typeof(UIntPtr) && t != typeof(IntPtr);
        }
    }
}
